package mammuthus.command

import java.io.File
import org.apache.commons.io.FileUtils
import mammuthus.slave.ShellCommand
import mammuthus.tool.TemplateTool

/**
 * 5/17/15 WilliamZhu(allwefantasy@gmail.com)
 */
trait PidCommand {
  def appPidsCollect(appName: String, installPath: String): List[Map[String, Map[String, String]]] = {
    val appDir = s"$installPath/${appName}"
    val appPids = new File(s"$appDir/pids")
    if (!appPids.exists()) return List()
    appPids.listFiles.map {
      pidFile =>
        val pid = FileUtils.readFileToString(pidFile).trim
        if (checkPid(pid))
          Map("app" -> Map("moduleName" -> pidFile.getName, "pid" -> pid),
            "cpu" -> appCPU(pid),
            "mem" -> appMem(pid),
            "gc" -> appGC(pid)
          )
        else Map[String, Map[String, String]]()
    }.filterNot(f => f.isEmpty).toList
  }

  def checkPid(pid: String): Boolean = {
    val res = ShellCommand.exec(shellTemplate("processCheck", Map("pid" -> pid)))
    val tt = res.split("\n")
    if (tt.length != 2) return false
    return tt.map(f => f.split("\\s+")).filter(f => f(1) == pid).size > 0
  }

  //11:18:17 AM      4561   23.64    1.40    0.00   25.04     6  java
  def appCPU(pid: String) = {
    try {
      val res = ShellCommand.exec(shellTemplate("process", Map("pid" -> pid)))
      val Array(usr, system, guest, cpu, cpuNum, command) = res.split("\n").last.split("\\s+").takeRight(6)
      Map("usr" -> usr, "system" -> system, "command" -> command)
    } catch {
      case e: Exception =>
        Map[String, String]()
    }
  }

  def appMem(pid: String) = {
    try {
      val res = ShellCommand.exec(shellTemplate("processMem", Map("pid" -> pid)))
      val Array(minflt, majflt, vsz, rss, mem, command) = res.split("\n").last.split("\\s+").takeRight(6)
      Map("vsz" -> vsz, "rss" -> rss, "memPercent" -> mem, "command" -> command)
    } catch {
      case e: Exception =>
        Map[String, String]()
    }
  }

  def appGC(pid: String): Map[String, String] = {
    val res = ShellCommand.exec(shellTemplate("processGC", Map("pid" -> pid)))
    val tt = res.split("\n").last.split("\\s+")
    if (tt.length != 10) return Map()
    Map("s0" -> tt(0),
      "s1" -> tt(1),
      "e" -> tt(2),
      "o" -> tt(3),
      "p" -> tt(4),
      "ygc" -> tt(5),
      "ygct" -> tt(6),
      "fgc" -> tt(7),
      "fgct" -> tt(8),
      "gct" -> tt(9)
    )
  }

  private def shellTemplate(shellName: String, params: Map[String, String] = Map()) = {
    TemplateTool.render(s"/template/command/shell/${shellName}.vm", params)
  }
}
